(function (exports, global) {
    var Protobuf = exports;
    Protobuf.init = function (opts) {
        //On the serverside, use serverProtos to encode messages send to client 
        Protobuf.protos = Protobuf.Root.fromJSON(JSON.parse(opts.proto));
        console.log('Protobuf.init',Protobuf.protos)
    };

    Protobuf.localInit = function () {
        //On the serverside, use serverProtos to encode messages send to client  
        Protobuf.protos_code = require('./proto') || {};
        // Protobuf.protos_third_code = Protobuf.protos_code;  
    };

    function findScopeFn(key) {
        if (!!!Protobuf.protos_code) {
            console.log('Protobuf.protos_code',Protobuf.protos_code)
            Protobuf.localInit();
        }
        var scope = null;
        try {
            scope = Protobuf.protos_third_code[key]; 
        } catch (e) { console.error('Protobuf.protos_third_code error', e) }
        if (!!!scope) {
            try {
                scope = Protobuf.protos_code[key];
            } catch (e) { console.error('Protobuf.protos_code error', e) } 
        }
        return scope;
    }

    Protobuf.encode = function (key, msg) {
        var rs = key.split('.');
        var m = null;
        if (Protobuf.protos) {
            var t = rs[0] + '.C_' + rs[2];
            try {
                m = Protobuf.protos.lookupType(t);
            } catch (e) { }
            if (m) {
                var en = m.encode(msg);
                var p = en.finish();
                return p;
            }
        }
        if (!!!m) {
            var _t = 'C_' + rs[2]; 
            var _scope_fn = findScopeFn(rs[0]);
            var _fn = (_scope_fn && _scope_fn[_t]['encode']) || null;
            if (_fn) {
                var _fn_en = _fn(msg);
                var _fn_p = _fn_en.finish(); 
                return _fn_p;
            }
        }
        return null;
    };

    Protobuf.decode = function (key, msg) {
        var rs = key.split('.');
        var m = null;
        if (Protobuf.protos) {
            var t = rs[0] + '.S_' + rs[2]; 
            try {
                m = Protobuf.protos.lookupType(t);
            } catch (e) { } 
            if (m) {
                var de = m.decode(msg);
                return de;
            }

        }
        if (!!!m) {
            var _t = 'S_' + rs[2]; 
            var _scope_fn = findScopeFn(rs[0]); 
            var _fn = (_scope_fn && _scope_fn[_t]['decode']) || null; 
            if (_fn) {
                var _fn_en = _fn(msg); 
                return _fn_en;
            }
        }
        return null;
    };

    // exports to support for components
    module.exports =  Protobuf;
})((function () {
    var protobuf = require('./protobuf.min')
    return 'undefined' !== typeof protobuf ? protobuf : module.exports;
})(), this);